import { ref, computed } from 'vue'
import useApi from '@/core/apiStore'
import type { NodeBusinessData } from '@/components/topo/types'
import { each, chain, find, filter, includes } from 'lodash'

export default function useTopoData() {
  const apiStore = useApi()

  const sections = ref([])
  const selectedNodeInfoList = ref([])

  const allClusterInfoList = computed(() => {
    const clusterList =
      apiStore.apiStates.getClusters.data?.data?.clusters || []
    return clusterList
  })

  const allNodeInfoList = computed(() => {
    return apiStore.apiStates.getNodes.data || []
  })

  const loadBusinessData = async (businessName: string) => {
    const businessItem = find(apiStore.apiStates.getBusinessItems.data, {
      name: businessName,
    })

    const { sections: _sections = [], clusters = [] } = businessItem || {}

    sections.value = _sections
    const selectedClusterInfoList = filter(
      allClusterInfoList.value,
      clusterInfo => {
        return includes(clusters, clusterInfo.name)
      }
    )
    const selectedIps = chain(selectedClusterInfoList)
      .map(item => item.ips)
      .flatten()
      .value()

    selectedNodeInfoList.value = filter(allNodeInfoList.value, nodeInfo => {
      return includes(selectedIps, nodeInfo.ip)
    })

    await apiStore.getBusinessNodes({ businessName })
  }

  const mergeNodes = (
    businessNodes: NodeBusinessData[]
  ): NodeBusinessData[] => {
    const filteredBusinessNodes = businessNodes.filter(bNode =>
      selectedNodeInfoList.value.some(node => node.ip === bNode.ip)
    )

    const newNodes = selectedNodeInfoList.value
      .filter(node => !businessNodes.some(bNode => bNode.ip === node.ip))
      .map(node => ({
        id: node.ip,
        ip: node.ip,
        name: node.name,
      }))

    const mergedNodes = [...filteredBusinessNodes, ...newNodes]

    each(mergedNodes, node => {
      const originNode = find(
        selectedNodeInfoList.value,
        item => item.ip === node.ip
      )
      node.name = originNode.name
      node.icon = originNode.icon
    })

    return mergedNodes
  }

  const nodeBusinessData = computed(() => {
    const businessNodes =
      apiStore.apiStates.getBusinessNodes.data?.nodeBusinessData || []

    return mergeNodes(businessNodes)
  })

  const nodeUIData = computed(() => {
    return apiStore.apiStates.getBusinessNodes.data?.nodeUIData || []
  })

  const reset = () => {
    apiStore.apiStates.getBusinessNodes.data?.nodeBusinessData.splice(0)
    apiStore.apiStates.getBusinessNodes.data?.nodeUIData.nodes.splice(0)
    apiStore.apiStates.getBusinessNodes.data?.nodeUIData.edges.splice(0)
    apiStore.apiStates.getBusinessMiddle.data.splice(0)
  }

  const loadTopoData = async (businessName1: string) => {
    reset()
    await Promise.all([
      apiStore.getNodes(),
      apiStore.getBusinessItems(),
      apiStore.getClusters(),
    ])
    await loadBusinessData(businessName1)
  }

  return {
    sections,
    nodeBusinessData,
    nodeUIData,
    loadTopoData,
  }
}
